home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / math / differ.zip / DIFFEREN.C < prev    next >
C/C++ Source or Header  |  1996-02-11  |  18KB  |  516 lines

  1. #include "differ.h"
  2.  
  3. /*
  4.    Copytree is useful to well copy trees !
  5.    It takes an expression and makes another copy of it.
  6. */
  7.  
  8. struct expression *copytree(struct expression *expr)
  9. { struct expression *coptree;
  10.   if (expr==NULL) return NULL;
  11.   coptree=newtree();
  12.   coptree->expval=expr->expval;
  13.   coptree->exptype=expr->exptype;
  14.   switch(coptree->exptype)
  15.   { case OPERATOR:  coptree->expval.op=expr->expval.op;
  16.               break;
  17.     case VALUE:     coptree->cval=expr->cval;
  18.               break;
  19.     case CONSTANT:  coptree->expval.co=expr->expval.co;
  20.               break;
  21.     case FUNCTION:  coptree->expval.fn=expr->expval.fn;
  22.               break;
  23.     case X:
  24.     case UNDEF_ETYPE:
  25.     default:;
  26.   }
  27.   coptree->lval=copytree(expr->lval);
  28.   coptree->rval=copytree(expr->rval);
  29.   return coptree;
  30. }
  31.  
  32. /*
  33.    This routine is one of the workhorses of the program. It takes an
  34.    expression tree and differentiates it. Note that we must take of
  35.    differentiating f1(x) ^ f2(x) say and not just f1(x) ^ n.
  36.    This is one of the reasons why it is so complicated and simplifying
  37.    will be necessary to get of extraneous bits. As it stands now it can
  38.    differentiate most things.
  39.  
  40.    I never got round to adding ARCCOT,ARCSEC,ARCCOSEC and the associated
  41.    hyperbolic functions, but at the same time I haven't actually seen any
  42.    problems with these in. Just about every other trig/hyp function is
  43.    there though. Of course it supports functions of functions etc.
  44. */
  45.  
  46. struct expression *differentiate(struct expression *expr)
  47. { struct expression *temptree,
  48.               *dtree;
  49.   if(expr==NULL) return NULL;
  50.   switch(expr->exptype)
  51.   { case OPERATOR:   switch(expr->expval.op)
  52.                { case MINUS:
  53.                  case PLUS:    expr->lval=differentiate(expr->lval);
  54.                          expr->rval=differentiate(expr->rval);
  55.                          return expr;
  56.                  case TIMES:   expr->expval.op=PLUS;
  57.                          temptree=newtree();
  58.                          temptree->exptype=OPERATOR;
  59.                          temptree->expval.op=TIMES;
  60.                          temptree->lval=expr->lval;
  61.                          expr->lval=temptree;
  62.                          temptree=newtree();
  63.                          temptree->exptype=OPERATOR;
  64.                          temptree->expval.op=TIMES;
  65.                          temptree->lval=expr->rval;
  66.                          expr->rval=temptree;
  67.                          expr->lval->rval=differentiate(copytree(expr->rval->lval));
  68.                          expr->rval->rval=differentiate(copytree(expr->lval->lval));
  69.                          return expr;
  70.                  case DIVIDE:  temptree=newtree();
  71.                          temptree->exptype=OPERATOR;
  72.                          temptree->expval.op=TIMES;
  73.                          temptree->lval=expr->rval;
  74.                          temptree->rval=copytree(temptree->lval);
  75.                          expr->rval=temptree;
  76.                          temptree=newtree();
  77.                          temptree->exptype=OPERATOR;
  78.                          temptree->expval.op=MINUS;
  79.                          temptree->rval=expr->lval;
  80.                          expr->lval=temptree;
  81.                          temptree=newtree();
  82.                          temptree->exptype=OPERATOR;
  83.                          temptree->expval.op=TIMES;
  84.                          temptree->lval=expr->lval->rval;
  85.                          expr->lval->rval=temptree;
  86.                          temptree=newtree();
  87.                          temptree->exptype=OPERATOR;
  88.                          temptree->expval.op=TIMES;
  89.                          temptree->lval=copytree(expr->rval->rval);
  90.                          expr->lval->lval=temptree;
  91.                          expr->lval->lval->rval=differentiate(copytree(expr->lval->rval->lval));
  92.                          expr->lval->rval->rval=differentiate(copytree(expr->rval->rval));
  93.                          return expr;
  94.                  case POWER:   temptree=newtree();
  95.                          temptree->exptype=OPERATOR;
  96.                          temptree->expval.op=TIMES;
  97.                          temptree->rval=expr;
  98.                          expr=temptree;
  99.                          temptree=newtree();
  100.                          temptree->exptype=OPERATOR;
  101.                          temptree->expval.op=PLUS;
  102.                          expr->lval=temptree;
  103.                          temptree=newtree();
  104.                          temptree->exptype=OPERATOR;
  105.                          temptree->expval.op=TIMES;
  106.                          expr->lval->lval=temptree;
  107.                          temptree=newtree();
  108.                          temptree->exptype=OPERATOR;
  109.                          temptree->expval.op=TIMES;
  110.                          expr->lval->rval=temptree;
  111.                          temptree=newtree();
  112.                          temptree->exptype=OPERATOR;
  113.                          temptree->expval.op=DIVIDE;
  114.                          expr->lval->rval->rval=temptree;
  115.                          temptree=newtree();
  116.                          temptree->exptype=FUNCTION;
  117.                          temptree->expval.op=LN;
  118.                          expr->lval->lval->rval=temptree;
  119.                          expr->lval->lval->rval->rval=copytree(expr->rval->lval);
  120.                          expr->lval->rval->rval->rval=copytree(expr->rval->lval);
  121.                          expr->lval->rval->rval->lval=copytree(expr->rval->rval);
  122.                          expr->lval->lval->lval=differentiate(copytree(expr->rval->rval));
  123.                          expr->lval->rval->lval=differentiate(copytree(expr->rval->lval));
  124.                          return expr;
  125.                  case UMINUS:  expr->rval=differentiate(expr->rval);
  126.                          return expr;
  127.                  case UNDEF_OP:
  128.                  default:      printf("undefined operator in expression\n\r");
  129.                          return expr;
  130.                }
  131.     case VALUE:      expr->cval=0;
  132.                return expr;
  133.     case CONSTANT:   expr->exptype=VALUE;
  134.                expr->cval=0;
  135.                return expr;
  136.     case X:          expr->exptype=VALUE;
  137.                expr->cval=1;
  138.                return expr;
  139.     case FUNCTION:   switch(expr->expval.fn)
  140.                { case SIN:       temptree=newtree();
  141.                            temptree->exptype=OPERATOR;
  142.                            temptree->expval.op=TIMES;
  143.                            temptree->rval=expr;
  144.                            expr->expval.fn=COS;
  145.                            temptree->lval=differentiate(copytree(expr->rval));
  146.                            return temptree;
  147.                  case EXP:       temptree=newtree();
  148.                            temptree->exptype=OPERATOR;
  149.                            temptree->expval.op=TIMES;
  150.                            temptree->rval=expr;
  151.                            temptree->lval=differentiate(copytree(expr->rval));
  152.                            return temptree;
  153.                  case LN:        expr->exptype=OPERATOR;
  154.                            expr->expval.op=DIVIDE;
  155.                            expr->lval=differentiate(copytree(expr->rval));
  156.                            return expr;
  157.                  case COS:       temptree=newtree();
  158.                            temptree->exptype=OPERATOR;
  159.                            temptree->expval.op=TIMES;
  160.                            temptree->rval=expr;
  161.                            expr->expval.fn=SIN;
  162.                            expr=temptree;
  163.                            temptree=newtree();
  164.                            temptree->exptype=OPERATOR;
  165.                            temptree->expval.op=UMINUS;
  166.                            temptree->rval=expr;
  167.                            expr=temptree;
  168.                            expr->rval->lval=differentiate(copytree(expr->rval->rval->rval));
  169.                            return expr;
  170.                  case TAN:       expr->expval.fn=SEC;
  171.                            temptree=newtree();
  172.                            temptree->exptype=OPERATOR;
  173.                            temptree->expval.op=POWER;
  174.                            temptree->lval=expr;
  175.                            expr=temptree;
  176.                            temptree=newtree();
  177.                            temptree->exptype=VALUE;
  178.                            temptree->cval=2;
  179.                            expr->rval=temptree;
  180.                            temptree=newtree();
  181.                            temptree->exptype=OPERATOR;
  182.                            temptree->expval.op=TIMES;
  183.                            temptree->rval=expr;
  184.                            expr=temptree;
  185.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  186.                            return expr;
  187.                  case SEC:       temptree=newtree();
  188.                            temptree->exptype=OPERATOR;
  189.                            temptree->expval.op=TIMES;
  190.                            temptree->lval=expr;
  191.                            temptree->rval=copytree(expr);
  192.                            temptree->rval->expval.fn=TAN;
  193.                            expr=temptree;
  194.                            temptree=newtree();
  195.                            temptree->exptype=OPERATOR;
  196.                            temptree->expval.op=TIMES;
  197.                            temptree->rval=expr;
  198.                            expr=temptree;
  199.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  200.                            return expr;
  201.                  case COSEC:     temptree=newtree();
  202.                            temptree->exptype=OPERATOR;
  203.                            temptree->expval.op=TIMES;
  204.                            temptree->lval=expr;
  205.                            temptree->rval=copytree(expr);
  206.                            temptree->rval->expval.fn=COT;
  207.                            expr=temptree;
  208.                            temptree=newtree();
  209.                            temptree->exptype=OPERATOR;
  210.                            temptree->expval.op=TIMES;
  211.                            temptree->rval=expr;
  212.                            expr=temptree;
  213.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  214.                            temptree=newtree();
  215.                            temptree->exptype=OPERATOR;
  216.                            temptree->expval.op=UMINUS;
  217.                            temptree->rval=expr;
  218.                            return temptree;
  219.                  case COT:       expr->expval.fn=COSEC;
  220.                            temptree=newtree();
  221.                            temptree->exptype=OPERATOR;
  222.                            temptree->expval.op=POWER;
  223.                            temptree->lval=expr;
  224.                            expr=temptree;
  225.                            temptree=newtree();
  226.                            temptree->exptype=VALUE;
  227.                            temptree->cval=2;
  228.                            expr->rval=temptree;
  229.                            temptree=newtree();
  230.                            temptree->exptype=OPERATOR;
  231.                            temptree->expval.op=TIMES;
  232.                            temptree->rval=expr;
  233.                            expr=temptree;
  234.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  235.                            temptree=newtree();
  236.                            temptree->exptype=OPERATOR;
  237.                            temptree->expval.op=UMINUS;
  238.                            temptree->rval=expr;
  239.                            return temptree;
  240.                  case SINH:      temptree=newtree();
  241.                            temptree->exptype=OPERATOR;
  242.                            temptree->expval.op=TIMES;
  243.                            temptree->rval=expr;
  244.                            expr->expval.fn=COSH;
  245.                            temptree->lval=differentiate(copytree(expr->rval));
  246.                            return temptree;
  247.                  case COSH:      temptree=newtree();
  248.                            temptree->exptype=OPERATOR;
  249.                            temptree->expval.op=TIMES;
  250.                            temptree->rval=expr;
  251.                            expr->expval.fn=SINH;
  252.                            temptree->lval=differentiate(copytree(expr->rval));
  253.                            return temptree;
  254.                  case TANH:      expr->expval.fn=SECH;
  255.                            temptree=newtree();
  256.                            temptree->exptype=OPERATOR;
  257.                            temptree->expval.op=POWER;
  258.                            temptree->lval=expr;
  259.                            expr=temptree;
  260.                            temptree=newtree();
  261.                            temptree->exptype=VALUE;
  262.                            temptree->cval=2;
  263.                            expr->rval=temptree;
  264.                            temptree=newtree();
  265.                            temptree->exptype=OPERATOR;
  266.                            temptree->expval.op=TIMES;
  267.                            temptree->rval=expr;
  268.                            expr=temptree;
  269.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  270.                            return expr;
  271.                  case SECH:      temptree=newtree();
  272.                            temptree->exptype=OPERATOR;
  273.                            temptree->expval.op=TIMES;
  274.                            temptree->lval=expr;
  275.                            temptree->rval=copytree(expr);
  276.                            temptree->rval->expval.fn=TANH;
  277.                            expr=temptree;
  278.                            temptree=newtree();
  279.                            temptree->exptype=OPERATOR;
  280.                            temptree->expval.op=TIMES;
  281.                            temptree->rval=expr;
  282.                            expr=temptree;
  283.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  284.                            temptree=newtree();
  285.                            temptree->exptype=OPERATOR;
  286.                            temptree->expval.op=UMINUS;
  287.                            temptree->rval=expr;
  288.                            return temptree;
  289.                  case COTH:      expr->expval.fn=COSECH;
  290.                            temptree=newtree();
  291.                            temptree->exptype=OPERATOR;
  292.                            temptree->expval.op=POWER;
  293.                            temptree->lval=expr;
  294.                            expr=temptree;
  295.                            temptree=newtree();
  296.                            temptree->exptype=VALUE;
  297.                            temptree->cval=2;
  298.                            expr->rval=temptree;
  299.                            temptree=newtree();
  300.                            temptree->exptype=OPERATOR;
  301.                            temptree->expval.op=TIMES;
  302.                            temptree->rval=expr;
  303.                            expr=temptree;
  304.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  305.                            temptree=newtree();
  306.                            temptree->exptype=OPERATOR;
  307.                            temptree->expval.op=UMINUS;
  308.                            temptree->rval=expr;
  309.                            return temptree;
  310.                  case COSECH:    temptree=newtree();
  311.                            temptree->exptype=OPERATOR;
  312.                            temptree->expval.op=TIMES;
  313.                            temptree->lval=expr;
  314.                            temptree->rval=copytree(expr);
  315.                            temptree->rval->expval.fn=COTH;
  316.                            expr=temptree;
  317.                            temptree=newtree();
  318.                            temptree->exptype=OPERATOR;
  319.                            temptree->expval.op=TIMES;
  320.                            temptree->rval=expr;
  321.                            expr=temptree;
  322.                            expr->lval=differentiate(copytree(expr->rval->lval->rval));
  323.                            temptree=newtree();
  324.                            temptree->exptype=OPERATOR;
  325.                            temptree->expval.op=UMINUS;
  326.                            temptree->rval=expr;
  327.                            return temptree;
  328.                  case ARCSIN:    dtree=newtree();
  329.                            dtree->exptype=OPERATOR;
  330.                            dtree->expval.op=DIVIDE;
  331.                            temptree=newtree();
  332.                            temptree->exptype=OPERATOR;
  333.                            temptree->expval.op=POWER;
  334.                            dtree->rval=temptree;
  335.                            temptree=newtree();
  336.                            temptree->exptype=VALUE;
  337.                            temptree->cval=0.5;
  338.                            dtree->rval->rval=temptree;
  339.                            temptree=newtree();
  340.                            temptree->exptype=OPERATOR;
  341.                            temptree->expval.op=MINUS;
  342.                            dtree->rval->lval=temptree;
  343.                            temptree=newtree();
  344.                            temptree->exptype=VALUE;
  345.                            temptree->cval=1;
  346.                            dtree->rval->lval->lval=temptree;
  347.                            temptree=newtree();
  348.                            temptree->exptype=OPERATOR;
  349.                            temptree->expval.op=POWER;
  350.                            dtree->rval->lval->rval=temptree;
  351.                            temptree=newtree();
  352.                            temptree->exptype=VALUE;
  353.                            temptree->cval=2;
  354.                            dtree->rval->lval->rval->rval=temptree;
  355.                            dtree->rval->lval->rval->lval=expr->rval;
  356.                            dtree->lval=differentiate(copytree(expr->rval));
  357.                            expr->rval=NULL;
  358.                            freetree(expr);
  359.                            return dtree;
  360.                  case ARCCOS:    dtree=newtree();
  361.                            dtree->exptype=OPERATOR;
  362.                            dtree->expval.op=DIVIDE;
  363.                            temptree=newtree();
  364.                            temptree->exptype=OPERATOR;
  365.                            temptree->expval.op=POWER;
  366.                            dtree->rval=temptree;
  367.                            temptree=newtree();
  368.                            temptree->exptype=VALUE;
  369.                            temptree->cval=0.5;
  370.                            dtree->rval->rval=temptree;
  371.                            temptree=newtree();
  372.                            temptree->exptype=OPERATOR;
  373.                            temptree->expval.op=MINUS;
  374.                            dtree->rval->lval=temptree;
  375.                            temptree=newtree();
  376.                            temptree->exptype=VALUE;
  377.                            temptree->cval=1;
  378.                            dtree->rval->lval->lval=temptree;
  379.                            temptree=newtree();
  380.                            temptree->exptype=OPERATOR;
  381.                            temptree->expval.op=POWER;
  382.                            dtree->rval->lval->rval=temptree;
  383.                            temptree=newtree();
  384.                            temptree->exptype=VALUE;
  385.                            temptree->cval=2;
  386.                            dtree->rval->lval->rval->rval=temptree;
  387.                            dtree->rval->lval->rval->lval=expr->rval;
  388.                            dtree->lval=differentiate(copytree(expr->rval));
  389.                            expr->rval=NULL;
  390.                            freetree(expr);
  391.                            temptree=newtree();
  392.                            temptree->exptype=OPERATOR;
  393.                            temptree->expval.op=UMINUS;
  394.                            temptree->rval=dtree;
  395.                            return temptree;
  396.                  case ARCTAN:    dtree=newtree();
  397.                            dtree->exptype=OPERATOR;
  398.                            dtree->expval.op=DIVIDE;
  399.                            temptree=newtree();
  400.                            temptree->exptype=OPERATOR;
  401.                            temptree->expval.op=PLUS;
  402.                            dtree->rval=temptree;
  403.                            temptree=newtree();
  404.                            temptree->exptype=VALUE;
  405.                            temptree->cval=1;
  406.                            dtree->rval->lval=temptree;
  407.                            temptree=newtree();
  408.                            temptree->exptype=OPERATOR;
  409.                            temptree->expval.op=POWER;
  410.                            dtree->rval->rval=temptree;
  411.                            temptree=newtree();
  412.                            temptree->exptype=VALUE;
  413.                            temptree->cval=2;
  414.                            dtree->rval->rval->rval=temptree;
  415.                            dtree->rval->rval->lval=expr->rval;
  416.                            dtree->lval=differentiate(copytree(expr->rval));
  417.                            expr->rval=NULL;
  418.                            freetree(expr);
  419.                            return dtree;
  420.                  case ARCSINH:   dtree=newtree();
  421.                            dtree->exptype=OPERATOR;
  422.                            dtree->expval.op=DIVIDE;
  423.                            temptree=newtree();
  424.                            temptree->exptype=OPERATOR;
  425.                            temptree->expval.op=POWER;
  426.                            dtree->rval=temptree;
  427.                            temptree=newtree();
  428.                            temptree->exptype=VALUE;
  429.                            temptree->cval=0.5;
  430.                            dtree->rval->rval=temptree;
  431.                            temptree=newtree();
  432.                            temptree->exptype=OPERATOR;
  433.                            temptree->expval.op=PLUS;
  434.                            dtree->rval->lval=temptree;
  435.                            temptree=newtree();
  436.                            temptree->exptype=VALUE;
  437.                            temptree->cval=1;
  438.                            dtree->rval->lval->lval=temptree;
  439.                            temptree=newtree();
  440.                            temptree->exptype=OPERATOR;
  441.                            temptree->expval.op=POWER;
  442.                            dtree->rval->lval->rval=temptree;
  443.                            temptree=newtree();
  444.                            temptree->exptype=VALUE;
  445.                            temptree->cval=2;
  446.                            dtree->rval->lval->rval->rval=temptree;
  447.                            dtree->rval->lval->rval->lval=expr->rval;
  448.                            dtree->lval=differentiate(copytree(expr->rval));
  449.                            expr->rval=NULL;
  450.                            freetree(expr);
  451.                            return dtree;
  452.                  case ARCCOSH:   dtree=newtree();
  453.                            dtree->exptype=OPERATOR;
  454.                            dtree->expval.op=DIVIDE;
  455.                            temptree=newtree();
  456.                            temptree->exptype=OPERATOR;
  457.                            temptree->expval.op=POWER;
  458.                            dtree->rval=temptree;
  459.                            temptree=newtree();
  460.                            temptree->exptype=VALUE;
  461.                            temptree->cval=0.5;
  462.                            dtree->rval->rval=temptree;
  463.                            temptree=newtree();
  464.                            temptree->exptype=OPERATOR;
  465.                            temptree->expval.op=MINUS;
  466.                            dtree->rval->lval=temptree;
  467.                            temptree=newtree();
  468.                            temptree->exptype=VALUE;
  469.                            temptree->cval=1;
  470.                            dtree->rval->lval->rval=temptree;
  471.                            temptree=newtree();
  472.                            temptree->exptype=OPERATOR;
  473.                            temptree->expval.op=POWER;
  474.                            dtree->rval->lval->lval=temptree;
  475.                            temptree=newtree();
  476.                            temptree->exptype=VALUE;
  477.                            temptree->cval=2;
  478.                            dtree->rval->lval->lval->rval=temptree;
  479.                            dtree->rval->lval->lval->lval=expr->rval;
  480.                            dtree->lval=differentiate(copytree(expr->rval));
  481.                            expr->rval=NULL;
  482.                            freetree(expr);
  483.                            return dtree;
  484.                  case ARCTANH:   dtree=newtree();
  485.                            dtree->exptype=OPERATOR;
  486.                            dtree->expval.op=DIVIDE;
  487.                            temptree=newtree();
  488.                            temptree->exptype=OPERATOR;
  489.                            temptree->expval.op=MINUS;
  490.                            dtree->rval=temptree;
  491.                            temptree=newtree();
  492.                            temptree->exptype=VALUE;
  493.                            temptree->cval=1;
  494.                            dtree->rval->lval=temptree;
  495.                            temptree=newtree();
  496.                            temptree->exptype=OPERATOR;
  497.                            temptree->expval.op=POWER;
  498.                            dtree->rval->rval=temptree;
  499.                            temptree=newtree();
  500.                            temptree->exptype=VALUE;
  501.                            temptree->cval=2;
  502.                            dtree->rval->rval->rval=temptree;
  503.                            dtree->rval->rval->lval=expr->rval;
  504.                            dtree->lval=differentiate(copytree(expr->rval));
  505.                            expr->rval=NULL;
  506.                            freetree(expr);
  507.                            return dtree;
  508.                  case UNDEF_FUNC:
  509.                  default:        printf("Undefined function in expression\n\r");
  510.                            return expr;
  511.                }
  512.     case UNDEF_ETYPE:
  513.     default:         printf("Undefined type in expression\n\r");
  514.                return expr;
  515.   }
  516. }